package au.edu.adelaide.mips_soft_core.board_interface_pc.ui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import au.edu.adelaide.mips_soft_core.board_interface_pc.core.Core;

public class UploadMemoryPanel extends JPanel implements ActionListener{
	
	JComboBox<Integer> memoryModuleSelector = new JComboBox<Integer>(new Integer[]{1});
	
	JButton selectFileButton = new JButton("Select ASM File");
	JButton downloadButton = new JButton("DOWNLOAD!");
	
	File file = null;
	
	UI ui;
	
	public UploadMemoryPanel(UI ui){
		super(new GridBagLayout());
		this.ui = ui;
		addComponent(this, new JLabel("Memory Module"), 0, 0, 1, 1);
		addComponent(this, memoryModuleSelector, 1, 0, 1, 1);
		addComponent(this, new JLabel("Available Size"), 0, 1, 1, 1);
		addComponent(this, new JLabel("500 words (2k bytes)"), 1, 1, 1, 1);
		addComponent(this, selectFileButton, 0, 2, 2, 1);
		addComponent(this, new JLabel("Free Space Available"), 0, 3, 1, 1);
		addComponent(this, new JLabel("50 words"), 1, 3, 1, 1);
		addComponent(this, new JLabel("Fill Empty Space With"), 0, 4, 1, 1);
		addComponent(this, new JTextField("0xFFFFFFFF"), 1, 4, 1, 1);
		addComponent(this, downloadButton, 0, 5, 2, 1);
		this.downloadButton.addActionListener(this);
		this.selectFileButton.addActionListener(this);
	}
	
	public void updatePanel(){
		this.memoryModuleSelector.removeAllItems();
		int n = ui.connectedDevice.numberOfMemoryModules();
		for(int i = 0; i < n; i++){
			this.memoryModuleSelector.addItem(i);
		}
	}
	
	private void addComponent(JPanel panel, JComponent component, int x, int y, int width, int height){
		 GridBagConstraints c = new GridBagConstraints();
		 c.gridx = x;
		 c.gridy = y;
		 c.gridheight = height;
		 c.gridwidth = width;
		 panel.add(component,  c);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == this.selectFileButton){
			JFileChooser jfc = new JFileChooser("Select File");
			int result = jfc.showOpenDialog(this);
			if(result != JFileChooser.APPROVE_OPTION){
				return;
			}
			this.file = jfc.getSelectedFile();
		}else if(e.getSource() == this.downloadButton){
			try {
				FileInputStream in = new FileInputStream(this.file);
				long fileSize = this.file.length();
				byte selectedMem = (byte)this.memoryModuleSelector.getSelectedIndex();
				int maxSize = this.ui.connectedDevice.sizeOfMemoryModule(selectedMem);
				System.out.println("uploading to memory mod " + selectedMem + " " + maxSize + " : " + fileSize);
				if(fileSize % 4 != 0){
					fileSize = fileSize - (fileSize % 4);
				}
				if(fileSize == 0){
					return;
				}
				if(fileSize > maxSize * 4){
					fileSize = maxSize * 4;
				}
				byte[] buffer = new byte[(int)fileSize];
				int amount = 0;
				int read = in.read(buffer, 0, buffer.length);
				while(read != -1){
					amount += read;
					if(amount != buffer.length){
						read = in.read(buffer, amount, buffer.length - amount);
					}else{
						break;
					}
				}
				
				int bo = JOptionPane.showConfirmDialog(this, "Do you wish to swap byte order", "Byte Order", JOptionPane.YES_NO_OPTION);
				if(bo == JOptionPane.YES_OPTION){
					for(int i = 0; i < fileSize; i+=4){
						byte a = buffer[i];
						buffer[i] = buffer[i + 3];
						buffer[i + 3] = a;
						a = buffer[i+ 1];
						buffer[i + 1] = buffer[i + 2];
						buffer[i + 2] = a;
					}
				}
				
				
				this.ui.connectedDevice.uploadToBoardMemory(selectedMem, buffer);
				in.close();
				Core.getCore().getLogger().write("DONE WRITING TO BOARD", Core.LOG_LEVEL_MESSAGE);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
	}

}
